#ifndef DYN_ODE_SI_H
#define DYN_ODE_SI_H

#include "dyn_ode.h"
#include "../utilities/dyn_multifunctor_hamiltonian.h"

/*! \brief Symplectic integrator base class.
 *
 *  \date 10-01-2013
 *
 *  \author Joey Dumont <joey.dumont@gmail.com>
 *
 * This abstract class implements the next() pure virtual
 * function for symplectic integrators. Most symplectic integrators
 * deal with seperable hamiltonians, so this specialization is not that bad.
 */

class SI : public ODE
{
public:
    /*! The constructor specifies the Hamiltonian
     * under study. We assume throughout that the
     * initial time is \f$t=0\f$. We will initiliaze
     * it as such in the ODE constructor.
     */
    SI(HamiltonianSystem& func,
       colvec _initCond,
       double _end,
       double _initStepsize)
        : ODE(func,_initCond,0.0,_end,_initStepsize), system(func){}

    /*! @name Inherited Pure Virtual Functions
     * We implement the next() method here.
     */
    //@{
    colvec next(colvec previousStep);
    //@}

    /*! @name Accessor Functions */
    //@{
    HamiltonianSystem& getHamiltonianSytem(){return system;}
    int getNumberSteps(){return M;}
    int getOrder(){return order;}
    colvec getPositionCoefficients(){return c;}
    colvec getMomentumCoefficients(){return d;}

    void setHamiltonianSystem(HamiltonianSystem& _func){system=_func;}
    //@}

protected:
    /*! @name Symplectic Integrator Variables
     * We will need the system under study,
     * the number of steps in the evaluation, the
     * order and the vectors of coefficients. See
     * Winter Solstice Report (2013) for more details.
     */
    //@{
    HamiltonianSystem& system;  /// System under study
    int M;                      /// Number of steps in symplectic transformation
    int order;                  /// Order of the method
    colvec c;                   /// Position coefficients
    colvec d;                   /// Momentum coefficients
    //@}
};

#endif // DYN_ODE_SI_H
